package com.share.hibernate.baseDaoSupport.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Repository;

import com.share.hibernate.baseDaoSupport.BaseDao;


/**
 * BaseDaoHibernateSupport 基础类
 * @author xianwei
 *
 * @param <T>
 */

@SuppressWarnings("unchecked")
@Repository
public class BaseDaoHibernateSupport<T extends Serializable> implements
		BaseDao<T> {
	/**
	 * 注入SessionFactory对象
	 */
	@Resource
	private SessionFactory sessionFactory;
	private Class<T> entityClass;

	public BaseDaoHibernateSupport() {
		/*this.entityClass = ((Class) ((java.lang.reflect.ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[0]);*/
		this.entityClass = null;
		   Class<?> c = getClass();
		   Type type = c.getGenericSuperclass();
		   if (type instanceof ParameterizedType) {
		    Type[] parameterizedType = ((ParameterizedType) type)
		      .getActualTypeArguments();
		    this.entityClass = (Class<T>) parameterizedType[0];
		   }
	}

	/**
	 * 获取hibernate session
	 * 
	 * @return
	 */
	protected final Session getCurrentSession() {
		return sessionFactory.getCurrentSession();
	}

	/**
	 * 增加
	 */

	@Override
	public String save(T o) {
		Serializable result = getCurrentSession().save(o);
		if (result != null) {
			return String.valueOf(result);
		}
		return String.valueOf(0);
	}

	/**
	 * 删除
	 */
	@Override
	public String delete(T paramT) {
		try{
			getCurrentSession().delete(paramT);
			return String.valueOf(1);
		}catch (Exception e) {
			return String.valueOf(0);
		}
		
	}

	/**
	 * 修改
	 */
	@Override
	public String update(T o) {
		try{
			getCurrentSession().saveOrUpdate(o);
			return String.valueOf(1);
		}catch (Exception e) {
			return String.valueOf(0);
		}
		
		
	}

	/**
	 * 查询单个 按ID
	 */
	@Override
	public T getById(String id) {
		return (T) getCurrentSession().get(this.entityClass, id);
	}

	/**
	 * 查询单个 按HQL语句
	 */
	public T get(String HQL) {
		Query query = getCurrentSession().createQuery(HQL);
		List<?> list = query.list();
		if ((list != null) && (list.size() > 0)) {
			return (T) list.get(0);
		}
		return null;
	}
	/**
	 * 执行HQL语句
	 */
	public String execute(String HQL,Map<String, Object> params) {
		Query query = getCurrentSession().createQuery(HQL);
		for (String key : params.keySet()) {
			if(params.get(key) instanceof ArrayList<?>){
				query.setParameterList(key, (Collection<?>) params.get(key));
			}else{
				query.setParameter(key, params.get(key));	
			}
		}
		return String.valueOf(query.executeUpdate());
	}
	/**
	 * 查询单个 按HQL语句
	 */
	public T get(String HQL,Map<String, Object> params) {
		Query query = getCurrentSession().createQuery(HQL);
		for (String key : params.keySet()) {
			query.setParameter(key, params.get(key));	
		}
		List<?> list = query.list();
		if ((list != null) && (list.size() > 0)) {
			return (T) list.get(0);
		}
		return null;
	}
	/**
	 * 查询所有
	 */

	@Override
	public List<T> find() {
		Query query = getCurrentSession().createQuery(
				"from " + this.entityClass.getName());
		List<?> list = query.list();
		if ((list != null) && (list.size() > 0)) {
			return (List<T>) list;
		}
		return null;
	}

	/**
	 * 查询HQL语句
	 * 
	 * @param HQL
	 * @return
	 */
	public List<T> find(String HQL) {
		Query query = getCurrentSession().createQuery(HQL);
		List<?> list = query.list();
		if ((list != null) && (list.size() > 0)) {
			return (List<T>) list;
		}
		return null;
	}
	/**
	 * 查询HQL语句及参数对应
	 * 
	 * @param HQL
	 * @param params
	 * @return
	 */
	public List<T> find(String HQL, Map<String, Object> params) {
		Query query = getCurrentSession().createQuery(HQL);
		for (String key : params.keySet()) {
			if(params.get(key) instanceof ArrayList<?>){
				query.setParameterList(key, (Collection<?>) params.get(key));
			}else{
				query.setParameter(key, params.get(key));	
			}
		}
		List<?> list = query.list();
		if ((list != null) && (list.size() > 0)) {
			return (List<T>) list;
		}
		return null;
	}
	/**
	 * 查询HQL语句及参数对应
	 * 
	 * @param HQL
	 * @param params
	 * @return
	 */
	public List<T> find(String HQL, Map<String, Object> params,boolean cacheable) {
		Query query = getCurrentSession().createQuery(HQL);
		for (String key : params.keySet()) {
			if(params.get(key) instanceof ArrayList<?>){
				query.setParameterList(key, (Collection<?>) params.get(key));
			}else{
				query.setParameter(key, params.get(key));	
			}
		}
		if(cacheable){
			query.setCacheable(true);
		}
		List<?> list = query.list();
		if ((list != null) && (list.size() > 0)) {
			return (List<T>) list;
		}
		return null;
	}
	@Override
	public Integer getAgg() {
		Query query = getCurrentSession().createQuery(
				"from " + this.entityClass.getName());
		List<?> list = query.list();
		if ((list != null) && (list.size() > 0)) {
			return Integer.valueOf(list.size());
		}
		return Integer.valueOf(0);
	}
	
	@Override
	public Integer getAgg(String HQL) {
		Query query = getCurrentSession().createQuery(HQL);
		return Integer.valueOf(query.uniqueResult().toString());
	}

	@Override
	public Integer getAgg(String HQL, Map<String, Object> params) {
		Query query = getCurrentSession().createQuery(HQL);
		for (String key : params.keySet()) {
			if(params.get(key) instanceof ArrayList<?>){
				query.setParameterList(key, (Collection<?>) params.get(key));
			}else{
				query.setParameter(key, params.get(key));	
			}
		}
		return Integer.valueOf(query.uniqueResult().toString());
	}

	@Override
	public List<T> find(String HQL, Integer maxResults, Integer firstResult) {
		Query query = getCurrentSession().createQuery(HQL);
		query.setMaxResults(maxResults);
		query.setFirstResult(firstResult);
		List<?> list = query.list();
		if ((list != null) && (list.size() > 0)) {
			return (List<T>) list;
		}
		return null;
	}

	@Override
	public List<T> find(String HQL, Integer maxResults, Integer firstResult,
			 Map<String, Object> params) {
		Query query = getCurrentSession().createQuery(HQL);
		for (String key : params.keySet()) {
			if(params.get(key) instanceof ArrayList<?>){
				query.setParameterList(key, (Collection<?>) params.get(key));
			}else{
				query.setParameter(key, params.get(key));	
			}
		}
		query.setMaxResults(maxResults);
		query.setFirstResult(firstResult);
		List<?> list = query.list();
		if ((list != null) && (list.size() > 0)) {
			return (List<T>) list;
		}
		return null;
	}


	@Override
	public List<T> find(Integer maxResults, Integer firstResult) {
		Query query = getCurrentSession().createQuery(
				"from " + this.entityClass.getName());
		query.setMaxResults(maxResults);
		query.setFirstResult(firstResult);
		List<?> list = query.list();
		if ((list != null) && (list.size() > 0)) {
			return (List<T>) list;
		}
		return null;
	}

}
